package estadistec.grafico;

import java.awt.Color;
import java.beans.PropertyVetoException;

import javax.swing.*;

import estadistec.logica.tabla.TipoTabla;
import estadistec.logica.LEscritorio;
import estadistec.logica.tabla.LTabla;
import estadistec.logica.tabla.LTablaNormal;

/**
 * @author julatec
 * @author pcorrales
 * @author lecarrera
 */

/**
 * Clase contenedora a nivel grafico de los elementos graficas y tablas.
 * es el espacio en el cual se desarrolla el uso de la aplicacion
 * cada escritorio  posee un llave que lo identifica  y lo asocia con  los 
 * componentes que se agregaron a este escritorio.
 *
 * 2009-11-22: Se modifica la construcción del nombre, la cual se realiza en
 * la parte lógica.
 */

public class GEscritorio  extends JDesktopPane implements ConstantesGraficas
{

      /**
       * posicion x tabla
       */
      private int _posicionXTabla;
      
      /**
       * posicion y tabla
       */
      private int _posicionYTabla;
      
      
	 /**
	  * Escritorio logico que maneja este escritorio.
	  */
	  private LEscritorio _lEscritorio;
	  
	  private int _frameDistance;
	
	  /** 
	   * Constructor.
	   * 
	   * @param lEscritorio Escritorio lógico correspondiente.
	   * 
	   * @todo ¿Qué es "_frameDistance"?
	   */
	public GEscritorio(LEscritorio lEscritorio) 
	{
		super();
		
		_posicionXTabla = 0;
		_posicionYTabla = 0;
		_frameDistance = 0;
		
		
		/*
		 * cargar las dimensiones, la posicion y los colores del escritorio
		 */
		
		//this.setSize(CONFIG.cargarDimension("ESCRITORIO"));
		this.setLocation(CONFIG.cargarPunto("ESCRITORIO"));
		this.setBackground(ESTILO.getWhite());
		this.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
		//this.setAutoscrolls(true)
		this.setSize(990, 550);
		
	

		//this.setBorder(BorderFactory.createTitledBorder(" "));
	
		// El escritorio logico.
		this._lEscritorio = lEscritorio;
	}
	
	/**
	 * Metodo para retornar la llave del escritorio, que corresponde a la
	 * llave del escritorio logico.
	 */
	public long getLLave()
	{
		return this._lEscritorio.getLlave();
	}


	/** 
	 * Creación de la parte gráfica de una tabla.
	 * 
	 * @param lTabla La contraparte lógica.
	 * 
	 * @return Instancia.
	 *
	 * @todo Agregar Excepción por tipo de tabla en el switch.
	 */
	public GTabla crearTabla(LTabla lTabla) {

		TipoTabla tipo = lTabla.getTipo();
		String nombreTabla = lTabla.getNombre();

	   	/*
   		 * inicializar la instancia de una tabla
		 */
		GTabla gTabla;

		switch (tipo) 
		{
			case NORMAL :
				gTabla = new GTablaNormal((LTablaNormal) lTabla, nombreTabla);
				break;
				/*
			case MUESTRA :
				break;
			case RESUMEN :
				break;
				*/
			default:
				gTabla = new GTablaNormal((LTablaNormal) lTabla, nombreTabla);
				throw new RuntimeException("Tipo de tabla desconocido");
		}

		
		int width = (int)(this.getWidth () / 2.5);
	    int height = (int)(this.getHeight () / 1.5) ;
	     
	    gTabla.reshape ( _posicionXTabla, _posicionYTabla, width, height ) ;
        gTabla.iniciar();

          
        if (_frameDistance == 0 )
            _frameDistance =  gTabla.getHeight ()
                -  gTabla.getContentPane () .getHeight () ;

          // compute placement for next frame

          _posicionXTabla += _frameDistance;
          _posicionYTabla += _frameDistance;
          if ( _posicionXTabla + width > this.getWidth ())
        	  _posicionXTabla = 0 ;
          if ( _posicionYTabla + height > this.getHeight ())
        	  _posicionYTabla= 0 ;

			
		/*
		 * se le envia a la tabla  el escritorio al cual pertenece
		 */
		gTabla.agregarGEscritorio(this);

		// ¿Qué hace esto?
	    try {
			gTabla.setSelected(true);
		} catch (PropertyVetoException e) {
			e.printStackTrace();
		}
		
		/*
		 * agregarla al escritorio actual
		 */
		this.add(gTabla);
		
		/*
		 *ordenamiento por defecto 
		 */
		// ordenarCuadricula();
		// ordenarCascada();
		
		
		return gTabla;
		
	}

	/**
	 * 
	 */
	public void ordenarCascada() 
	{
	    JInternalFrame [] frames = this.getAllFrames () ;
	    int x = 0 ;
	    int y = 0 ;
		int width = (int)(this.getWidth () / 2.5);
	    int height = (int)(this.getHeight () / 1.5) ;

	     for ( int i = 0 ; i < frames.length; i++ ) {
	       if ( !frames [ i ] .isIcon ()) {
	         try { 
	           //frames [ i ] .setMaximum ( true) ;
	           frames [ i ] .reshape ( x, y, width, height ) ;

	           x += _frameDistance;
	           y += _frameDistance;


	           
	           if ( x + width > this.getWidth ())
	             x = 0 ;
	           if ( y + height > this.getHeight ())
	             y = 0 ;
	         } catch ( Exception E ) {
	         }
	       }
	     }
      }

	/**
	 * 
	 */
	public void ordenarCuadricula() {
	     JInternalFrame [] frames = this.getAllFrames () ;

	     int frameCount = 0 ;
	     for ( int i = 0 ; i < frames.length; i++ ) {
	       if ( !frames [ i ] .isIcon ())
	         frameCount++;
	     }

	     int rows = ( int ) Math.sqrt ( frameCount ) ;
	     int cols = frameCount / rows;
	     int extra = frameCount % rows;
	   

	     int width = this.getWidth () / cols;
	     int height = this.getHeight () / rows;
	     int r = 0 ;
	     int c = 0 ;
	     
	     for ( int i = 0 ; i < frames.length; i++ ) {
	       if ( !frames [ i ] .isIcon ()) 
	       {
	         try {
	           frames [ i ] .setMaximum ( false) ;
	           frames [ i ] .reshape ( c * width, r * height, width, height ) ;
	           r++;
	           if ( r == rows ) {
	             r = 0 ;
	             c++;
	             if ( c == cols - extra ) { // start adding an extra row
	               rows++;
	               height = this.getHeight () / rows;
	             }
	           }
	         } catch ( PropertyVetoException e ) {
	         }
	       }
	     }
	   }
}
